<template>
  <view class="appointment-detail">
    <!-- 状态头部 -->
    <view
      class="status-header"
      v-if="dntered === false"
      :class="[
        appointmentData.auditStatus === '0'
          ? 'status-pending'
          : appointmentData.auditStatus === '1'
          ? 'status-approved'
          : appointmentData.auditStatus === '2'
          ? 'status-inspection'
          : appointmentData.auditStatus === '3'
          ? 'status-rejected'
          : 'status-pending',
      ]"
    >
      <view class="status-icon">
        <uni-icons
          :type="
            appointmentData.auditStatus === '0'
              ? 'clock'
              : appointmentData.auditStatus === '1' ||
                (appointmentData.auditStatus === '2' && appointmentData.checkStatus === '1' && appointmentData.qrColor === '0')
              ? 'checkmarkempty'
              : appointmentData.auditStatus === '2' && appointmentData.checkStatus !== '1'
              ? 'scan'
              : appointmentData.auditStatus === '3' || (appointmentData.checkStatus === '1' && appointmentData.qrColor === '2')
              ? 'closeempty'
              : 'clock'
          "
          size="40"
          color="#fff"
        ></uni-icons>
      </view>
      <view class="status-info">
        <text class="status-text">{{
          appointmentData.auditStatus === '0'
            ? '待审核'
            : appointmentData.auditStatus === '1' ||
              (appointmentData.auditStatus === '2' && appointmentData.checkStatus === '1' && appointmentData.qrColor === '0')
            ? '审核通过'
            : appointmentData.auditStatus === '2' && appointmentData.checkStatus !== '1'
            ? '需要抽检'
            : appointmentData.checkStatus === '1' && appointmentData.qrColor === '2'
            ? '抽检不合格'
            : appointmentData.auditStatus === '3'
            ? '审核拒绝'
            : '未知状态'
        }}</text>
        <text class="status-desc">{{
          appointmentData.auditStatus === '0'
            ? '您的预约申请正在审核中，请耐心等待'
            : appointmentData.auditStatus === '1' ||
              (appointmentData.auditStatus === '2' && appointmentData.checkStatus === '1' && appointmentData.qrColor === '0')
            ? '预约审核通过，可以按时入场'
            : appointmentData.auditStatus === '2' && appointmentData.checkStatus !== '1'
            ? '需要配合现场抽检后方可入场'
            : appointmentData.checkStatus === '1' && appointmentData.qrColor === '2'
            ? '抽检不合格，无法入场'
            : appointmentData.auditStatus === '3'
            ? '预约申请被拒绝，请查看拒绝原因'
            : ''
        }}</text>
      </view>
    </view>

    <!-- 二维码展示 (通过、需抽检、抽检通过状态显示) -->
    <view
      class="qr-section"
      v-if="
        (appointmentData.auditStatus === '1' ||
          appointmentData.auditStatus === '2' ||
          (appointmentData.checkStatus === '1' && appointmentData.qrColor === '0')) &&
        appointmentData.qrCode
      "
    >
      <view class="qr-container">
        <view
          class="qr-code"
          :class="[
            isExpired || appointmentData.qrColor === '2'
              ? 'qr-border-red'
              : appointmentData.qrColor === '1'
              ? 'qr-border-yellow'
              : appointmentData.qrColor === '0'
              ? 'qr-border-green'
              : '',
          ]"
        >
          <!-- 直接显示后端生成的二维码图片 -->
          <image
            v-if="appointmentData.qrCode.startsWith('data:image')"
            :src="appointmentData.qrCode"
            mode="aspectFit"
            style="width: 100%; height: 100%"
          >
          </image>
          <!-- 如果不是图片格式，显示文本 -->
          <view v-else class="qr-text-content">
            <text>{{ appointmentData.qrCode }}</text>
          </view>

          <!-- 红码遮罩层 -->
          <view v-if="isExpired || appointmentData.qrColor === '2'" class="qr-mask">
            <uni-icons type="closeempty" size="60" color="#fff"></uni-icons>
            <text class="mask-text">已失效</text>
          </view>

          <!-- 已入场遮罩层 -->
          <view v-if="dntered === true" class="qr-mask green">
            <uni-icons type="checkmarkempty" size="60" color="#fff"></uni-icons>
            <text class="mask-text">已入场</text>
          </view>
        </view>
        <view class="qr-info" v-if="dntered === false">
          <view
            class="qr-color-tag"
            :class="[
              isExpired || appointmentData.qrColor === '2'
                ? 'qr-red'
                : appointmentData.qrColor === '0'
                ? 'qr-green'
                : appointmentData.qrColor === '1'
                ? 'qr-yellow'
                : 'qr-yellow',
            ]"
          >
            {{
              isExpired || appointmentData.qrColor === '2'
                ? '红码'
                : appointmentData.qrColor === '0'
                ? '绿码'
                : appointmentData.qrColor === '1'
                ? '黄码'
                : '黄码'
            }}
          </view>
          <text class="qr-desc">{{
            isExpired || appointmentData.qrColor === '2'
              ? '二维码已失效'
              : appointmentData.qrColor === '0' && appointmentData.checkStatus === '1'
              ? '抽检通过，请在入场时出示此二维码'
              : appointmentData.qrColor === '0'
              ? '请在入场时出示此二维码'
              : appointmentData.qrColor === '1' && appointmentData.checkStatus !== '1'
              ? '请在入场时出示此二维码，并配合抽检'
              : '请在入场时出示此二维码'
          }}</text>
        </view>
        <!-- 倒计时显示 -->
        <view class="countdown-box" v-if="(appointmentData.entryTime || appointmentData.appointmentDate) && dntered === false">
          <view v-if="!isExpired" class="countdown-timer">
            <uni-icons type="clock" size="18" color="#1890ff"></uni-icons>
            <text class="countdown-label">距离过期：</text>
            <text class="countdown-value" :class="countdownClass">{{ countdown }}</text>
          </view>
          <view v-else class="expired-notice">
            <uni-icons type="info-filled" size="18" color="#ff4d4f"></uni-icons>
            <text class="expired-text">二维码已过期</text>
          </view>
        </view>
      </view>
    </view>

    <!-- 预约信息 -->
    <view class="info-section">
      <view class="section-title">
        <uni-icons type="list" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">预约信息</text>
      </view>
      <view class="info-list">
        <view class="info-item">
          <text class="info-label">预约编号</text>
          <text class="info-value">{{ appointmentData.applyNo }}</text>
        </view>
        <view class="info-item">
          <text class="info-label">预约类型</text>
          <text class="info-value">{{
            appointmentData.purchaseType === '0' ? '食用农产品预约' : appointmentData.purchaseType === '1' ? '农批市场预约' : '其他预约'
          }}</text>
        </view>
        <view class="info-item">
          <text class="info-label">所属市场</text>
          <text class="info-value">{{ appointmentData.deptName || '未指定' }}</text>
        </view>
        <view class="info-item">
          <text class="info-label">入场车辆</text>
          <text class="info-value">{{ appointmentData.vehicleNo || '未填写' }}</text>
        </view>
        <view class="info-item">
          <text class="info-label">申请时间</text>
          <text class="info-value">{{ formatDateTime(appointmentData.createTime) }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.createBy && isManager">
          <text class="info-label">创建人</text>
          <text class="info-value">{{ appointmentData.createBy }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.entryTime">
          <text class="info-label">预约入场时间</text>
          <text class="info-value">{{ formatDateTime(appointmentData.entryTime) }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.entryPlace">
          <text class="info-label">入场地点</text>
          <text class="info-value">{{ appointmentData.entryPlace }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.contactPhone">
          <text class="info-label">联系电话</text>
          <text class="info-value">{{ appointmentData.contactPhone }}</text>
        </view>
      </view>
    </view>

    <!-- 商户信息（农批市场预约显示） -->
    <view class="info-section" v-if="appointmentData.purchaseType === '1' && appointmentData.merchantName">
      <view class="section-title">
        <uni-icons type="shop-filled" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">商户信息</text>
      </view>
      <view class="info-list">
        <view class="info-item">
          <text class="info-label">商户名称</text>
          <text class="info-value">{{ appointmentData.merchantName }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.merchantCode">
          <text class="info-label">商户编码</text>
          <text class="info-value">{{ appointmentData.merchantCode }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.businessLicense">
          <text class="info-label">营业执照</text>
          <view class="image-preview" @click="previewImage(appointmentData.businessLicense)">
            <image :src="appointmentData.businessLicense" mode="aspectFill" class="license-thumb"></image>
            <text class="view-text">点击查看</text>
          </view>
        </view>
        <view class="info-item" v-if="appointmentData.deliveryList">
          <text class="info-label">交货清单</text>
          <view class="image-preview" @click="previewImage(appointmentData.deliveryList)">
            <image :src="appointmentData.deliveryList" mode="aspectFill" class="license-thumb"></image>
            <text class="view-text">点击查看</text>
          </view>
        </view>
      </view>
    </view>

    <!-- 供货商信息（食用农产品预约显示） -->
    <view class="info-section" v-if="appointmentData.purchaseType === '0' && appointmentData.supplierName">
      <view class="section-title">
        <uni-icons type="personadd-filled" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">供货商信息</text>
      </view>
      <view class="info-list">
        <view class="info-item">
          <text class="info-label">供货商名称</text>
          <text class="info-value">{{ appointmentData.supplierName }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.originPlace">
          <text class="info-label">产地</text>
          <text class="info-value">{{ appointmentData.originPlace }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.totalAmount">
          <text class="info-label">货物总量</text>
          <text class="info-value">{{ appointmentData.totalAmount }} kg</text>
        </view>
      </view>
    </view>

    <!-- 商品信息 -->
    <view class="info-section" v-if="appointmentData.goodsList && appointmentData.goodsList.length > 0">
      <view class="section-title">
        <uni-icons type="shop" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">{{ appointmentData.purchaseType === '0' ? '货物明细' : '商品信息' }}</text>
        <view class="expand-toggle" @click="toggleAllGoods">
          {{ allGoodsExpanded ? '全部收起' : '全部展开' }}
          <uni-icons :type="allGoodsExpanded ? 'top' : 'bottom'" size="16" color="#1890ff"></uni-icons>
        </view>
      </view>
      <view class="goods-list">
        <view class="goods-card" v-for="(goods, index) in appointmentData.goodsList" :key="index">
          <!-- 商品头部 -->
          <view class="goods-header" @click="toggleGoodsExpand(index)">
            <view class="goods-badge">{{ index + 1 }}</view>
            <text class="goods-name">{{ goods.goodsName }}</text>
            <uni-icons :type="expandedGoods[index] ? 'top' : 'bottom'" size="20" color="#999"></uni-icons>
          </view>

          <!-- 商品详情（展开时显示） -->
          <view class="goods-content" v-if="expandedGoods[index]">
            <view class="goods-info-item">
              <text class="goods-label">{{ appointmentData.purchaseType === '0' ? '货物名称' : '商品名称' }}</text>
              <text class="goods-value">{{ goods.goodsName }}</text>
            </view>
            <view class="goods-info-item" v-if="appointmentData.purchaseType === '0' && goods.supplierName">
              <text class="goods-label">供货商</text>
              <text class="goods-value">{{ goods.supplierName }}</text>
            </view>
            <view class="goods-info-item">
              <text class="goods-label">数量</text>
              <text class="goods-value">{{ goods.quantity }}{{ goods.unit || 'kg' }}</text>
            </view>
            <view class="goods-info-item" v-if="appointmentData.purchaseType === '0'">
              <text class="goods-label">产地</text>
              <text class="goods-value">{{ goods.originPlace || appointmentData.originPlace || '-' }}</text>
            </view>
            <view class="goods-info-item" v-if="appointmentData.purchaseType === '0' && goods.vehicleNo">
              <text class="goods-label">车牌号</text>
              <text class="goods-value">{{ goods.vehicleNo }}</text>
            </view>
            <view class="goods-info-item" v-if="appointmentData.purchaseType === '1' && goods.goodsCategory">
              <text class="goods-label">商品分类</text>
              <text class="goods-value">{{ formatGoodsCategory(goods.goodsCategory) }}</text>
            </view>

            <!-- 对应凭证 -->
            <view class="goods-voucher-block">
              <text class="info-label">对应凭证</text>
              <view class="voucher-content">
                <!-- 进货凭证 -->
                <view class="voucher-row" v-if="goods.purchaseVoucher">
                  <text class="voucher-name">{{ appointmentData.purchaseType === '0' ? '进货凭证' : '采购凭证' }}</text>
                  <view class="voucher-status-box">
                    <text class="voucher-uploaded">已上传</text>
                    <image
                      class="voucher-thumbnail"
                      :src="goods.purchaseVoucher"
                      mode="aspectFill"
                      @click.stop="viewVoucher(goods.purchaseVoucher, '进货凭证')"
                    ></image>
                    <text class="voucher-link" @click.stop="viewVoucher(goods.purchaseVoucher, '进货凭证')">查看</text>
                  </view>
                </view>

                <!-- 承诺达标合格证（通用） -->
                <view class="voucher-row" v-if="goods.qualificationCert">
                  <text class="voucher-name">{{ appointmentData.purchaseType === '0' ? '承诺达标合格证' : '质检合格证' }}</text>
                  <view class="voucher-status-box">
                    <text class="voucher-uploaded">已上传</text>
                    <image
                      class="voucher-thumbnail"
                      :src="goods.qualificationCert"
                      mode="aspectFill"
                      @click.stop="viewVoucher(goods.qualificationCert, '合格证')"
                    ></image>
                    <text class="voucher-link" @click.stop="viewVoucher(goods.qualificationCert, '合格证')">查看</text>
                  </view>
                </view>

                <!-- 动物检疫合格证明（畜牧业产品） -->
                <view class="voucher-row" v-if="goods.animalQuarantineCert && isLivestockProduct(goods)">
                  <text class="voucher-name">动物检疫合格证明</text>
                  <view class="voucher-status-box">
                    <text class="voucher-uploaded">已上传</text>
                    <image
                      class="voucher-thumbnail"
                      :src="goods.animalQuarantineCert"
                      mode="aspectFill"
                      @click.stop="viewVoucher(goods.animalQuarantineCert, '动物检疫合格证明')"
                    ></image>
                    <text class="voucher-link" @click.stop="viewVoucher(goods.animalQuarantineCert, '动物检疫合格证明')">查看</text>
                  </view>
                </view>

                <!-- 肉品品质检验合格证（畜牧业产品） -->
                <view class="voucher-row" v-if="goods.meatQualityCert && isLivestockProduct(goods)">
                  <text class="voucher-name">肉品品质检验合格证</text>
                  <view class="voucher-status-box">
                    <text class="voucher-uploaded">已上传</text>
                    <image
                      class="voucher-thumbnail"
                      :src="goods.meatQualityCert"
                      mode="aspectFill"
                      @click.stop="viewVoucher(goods.meatQualityCert, '肉品品质检验合格证')"
                    ></image>
                    <text class="voucher-link" @click.stop="viewVoucher(goods.meatQualityCert, '肉品品质检验合格证')">查看</text>
                  </view>
                </view>

                <!-- 未上传 -->
                <view v-if="!hasAnyVoucher(goods)">
                  <text class="voucher-empty">未上传</text>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- 摊位信息 (农批市场预约) -->
    <view class="info-section" v-if="appointmentData.stallNumber">
      <view class="section-title">
        <uni-icons type="home" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">摊位信息</text>
      </view>
      <view class="info-list">
        <view class="info-item">
          <text class="info-label">摊位编号</text>
          <text class="info-value">{{ appointmentData.stallNumber }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.stallType">
          <text class="info-label">摊位类型</text>
          <text class="info-value">{{ appointmentData.stallType }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.leaseTerm">
          <text class="info-label">租赁期限</text>
          <text class="info-value">{{ appointmentData.leaseTerm }}</text>
        </view>
      </view>
    </view>

    <!-- 流程状态 -->
    <view class="info-section" v-if="appointmentData.processFlow && appointmentData.processFlow.length > 0">
      <view class="section-title">
        <uni-icons type="calendar-filled" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">流程状态</text>
      </view>
      <view class="process-flow">
        <view class="flow-item" v-for="(node, index) in appointmentData.processFlow" :key="index">
          <view class="flow-line" v-if="index > 0"></view>
          <view class="flow-node" :class="['flow-' + node.status]">
            <view class="node-icon">
              <uni-icons :type="getFlowIcon(node.status)" :size="16" :color="getFlowColor(node.status)"> </uni-icons>
            </view>
            <view class="node-content">
              <view class="node-title">{{ node.name }}</view>
              <view class="node-info" v-if="node.time || node.operator">
                <text class="node-time" v-if="node.time">{{ formatDateTime(node.time) }}</text>
                <text class="node-operator" v-if="node.operator">{{ node.operator }}</text>
              </view>
              <view class="node-remark" v-if="node.remark">
                <text class="remark-text">{{ node.remark }}</text>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- 审核信息 -->
    <view class="info-section" v-if="appointmentData.auditStatus !== '0'">
      <view class="section-title">
        <uni-icons type="checkmarkempty" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">审核信息</text>
      </view>
      <view class="info-list">
        <view class="info-item" v-if="appointmentData.auditTime">
          <text class="info-label">审核时间</text>
          <text class="info-value">{{ formatDateTime(appointmentData.auditTime) }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.auditUserName">
          <text class="info-label">审核人员</text>
          <text class="info-value">{{ appointmentData.auditUserName }}</text>
        </view>
        <view class="info-item" v-if="appointmentData.auditRemark">
          <text class="info-label">审核备注</text>
          <text class="info-value remark">{{ appointmentData.auditRemark }}</text>
        </view>
      </view>
    </view>

    <!-- 入场信息 -->
    <view class="info-section" v-if="dntered">
      <view class="section-title">
        <uni-icons type="checkmarkempty" size="20" color="#1890ff"></uni-icons>
        <text class="title-text">入场信息</text>
      </view>
      <view class="info-list">
        <view class="info-item">
          <text class="info-label">入场时间</text>
          <text class="info-value">{{ formatDateTime(dnteredInfo.time) }}</text>
        </view>
        <view class="info-item" v-if="dnteredInfo.operator">
          <text class="info-label">入场操作员</text>
          <text class="info-value">{{ dnteredInfo.operator }}</text>
        </view>
      </view>
    </view>

    <!-- 底部操作按钮 -->
    <view class="bottom-actions">
      <button class="action-btn" @click="goBack">
        <uni-icons type="back" size="18" color="#666"></uni-icons>
        <text class="action-text">返回</text>
      </button>
      <button class="action-btn primary" v-if="appointmentData.auditStatus === '1' || appointmentData.auditStatus === '2'" @click="showQrCode">
        <uni-icons type="scan" size="18" color="#fff"></uni-icons>
        <text class="action-text">显示二维码</text>
      </button>
      <button class="action-btn" v-if="appointmentData.auditStatus === '0'" @click="cancelAppointment">
        <uni-icons type="close" size="18" color="#ff4d4f"></uni-icons>
        <text class="action-text cancel">取消预约</text>
      </button>
    </view>
  </view>
</template>

<script>
import { getAppointment, delAppointment } from '@/api/business/appointment.js';

export default {
  data() {
    return {
      applyId: '',
      dntered: false,
      dnteredInfo: {},
      appointmentData: {
        applyId: '',
        applyNo: '',
        appointmentType: '0',
        vehicleNo: '',
        auditStatus: '0',
        qrCode: '',
        qrColor: '0',
        createTime: '',
        appointmentDate: '',
        appointmentTime: '',
        auditTime: '',
        auditUser: '',
        auditRemark: '',
        entryTime: '',
        entryOperator: '',
        originPlace: '',
        productionCompany: '',
        stallNumber: '',
        stallType: '',
        leaseTerm: '',
        goodsList: [],
      },
      // 倒计时相关
      countdown: '',
      isExpired: false,
      countdownTimer: null,
      // 商品展开状态
      expandedGoods: {},
      allGoodsExpanded: false,
    };
  },
  computed: {
    // 判断是否是管理人员（非商户角色）
    isManager() {
      const userInfo = uni.getStorageSync('userInfo') || {};
      const roles = userInfo.roles || [];
      // 判断是否有管理员、审核员、检验员等非商户角色
      return roles.some(
        (role) => ['admin', 'supervisor', 'checker', 'reviewer', 'inspector'].includes(role) || role.includes('admin') || role.includes('manage')
      );
    },
    // 倒计时样式类
    countdownClass() {
      if (this.isExpired) {
        return 'expired';
      }
      // 解析倒计时
      if (this.countdown.includes('小时') || this.countdown.includes('分钟')) {
        const match = this.countdown.match(/(\d+)/);
        if (match) {
          const num = parseInt(match[1]);
          if (this.countdown.includes('小时')) {
            if (num < 1) return 'urgent';
            if (num < 6) return 'warning';
          } else if (this.countdown.includes('分钟')) {
            if (num < 30) return 'urgent';
          }
        }
      }
      return 'normal';
    },
  },
  onLoad(options) {
    if (options.applyId) {
      this.applyId = options.applyId;
      this.loadAppointmentDetail();
    }
  },
  onUnload() {
    // 页面卸载时清理定时器
    if (this.countdownTimer) {
      clearInterval(this.countdownTimer);
      this.countdownTimer = null;
    }
  },
  methods: {
    // 判断是否为畜牧业产品
    isLivestockProduct(goods) {
      // 通过商品分类或产品类型判断是否为畜牧业产品
      // goodsCategory === '2' 表示畜牧业
      return goods.goodsCategory === '2' || goods.productType === '2';
    },

    // 判断是否有任何凭证
    hasAnyVoucher(goods) {
      return goods.purchaseVoucher || goods.qualificationCert || goods.animalQuarantineCert || goods.meatQualityCert;
    },

    // 加载预约详情
    async loadAppointmentDetail() {
      try {
        const response = await getAppointment(this.applyId);
        if (response.code === 200) {
          this.appointmentData = response.data || {};

          console.log('预约详情数据:', this.appointmentData);
          console.log('产地信息:', this.appointmentData.originPlace);
          console.log('流程状态数据:', this.appointmentData.processFlow);

          if (this.appointmentData.processFlow && this.appointmentData.processFlow.length > 0) {
            this.appointmentData.processFlow.forEach((item) => {
              if (item.name == '已入场') {
                this.dntered = true;
                this.dnteredInfo = item;
              }
            });
          }
          console.log('已入场:', this.dntered);

          // 启动倒计时
          this.startCountdown();

          // 后端返回的是appointmentDetailList，需要映射到goodsList
          if (this.appointmentData.appointmentDetailList) {
            this.appointmentData.goodsList = this.appointmentData.appointmentDetailList;
            console.log('商品列表:', this.appointmentData.goodsList);
            // 检查每个商品的产地信息
            this.appointmentData.goodsList.forEach((goods, index) => {
              console.log(`商品${index + 1}产地:`, goods.originPlace, '省:', goods.province);
            });
          } else {
            this.appointmentData.goodsList = [];
          }

          // 初始化商品展开状态（默认展开第一个）
          this.expandedGoods = {};
          if (this.appointmentData.goodsList && this.appointmentData.goodsList.length > 0) {
            this.$set(this.expandedGoods, 0, true); // 默认展开第一个商品
          }

          // 处理预约类型（后端返回的purchaseType需要映射到appointmentType）
          if (this.appointmentData.purchaseType === '0') {
            this.appointmentData.appointmentType = '0'; // 食用农产品
          } else if (this.appointmentData.purchaseType === '1') {
            this.appointmentData.appointmentType = '1'; // 农批市场
          }
        }
      } catch (error) {
        console.error('加载预约详情失败:', error);
        this.appointmentData = {};
        uni.showToast({
          title: '加载详情失败',
          icon: 'none',
          duration: 2000,
        });
      }
    },

    // 获取状态头部样式类
    getStatusHeaderClass(status) {
      const classMap = {
        0: 'status-pending',
        1: 'status-approved',
        2: 'status-inspection',
        3: 'status-rejected',
      };
      return classMap[status] || 'status-pending';
    },

    // 获取状态图标
    getStatusIcon(status) {
      const iconMap = {
        0: 'clock',
        1: 'checkmarkempty',
        2: 'scan',
        3: 'closeempty',
      };
      return iconMap[status] || 'clock';
    },

    // 获取状态文本
    getStatusText(status) {
      const textMap = {
        0: '待审核',
        1: '审核通过',
        2: '需要抽检',
        3: '审核拒绝',
      };
      return textMap[status] || '未知状态';
    },

    // 获取状态描述
    getStatusDesc(status) {
      const descMap = {
        0: '您的预约申请正在审核中，请耐心等待',
        1: '预约审核通过，可以按时入场',
        2: '需要配合现场抽检后方可入场',
        3: '预约申请被拒绝，请查看拒绝原因',
      };
      return descMap[status] || '';
    },

    // 获取二维码颜色样式类
    getQrColorClass(color) {
      return color === '0' ? 'qr-green' : 'qr-yellow';
    },

    // 获取二维码颜色文本
    getQrColorText(color) {
      return color === '0' ? '绿码' : '黄码';
    },

    // 启动倒计时
    startCountdown() {
      // 清理之前的定时器
      if (this.countdownTimer) {
        clearInterval(this.countdownTimer);
      }

      // 立即计算一次
      this.updateCountdown();

      // 每秒更新一次
      this.countdownTimer = setInterval(() => {
        this.updateCountdown();
      }, 1000);
    },

    // 更新倒计时
    updateCountdown() {
      // 获取入场时间，优先使用entryTime，否则使用appointmentDate + appointmentTime
      let entryTimeStr = this.appointmentData.entryTime;
      if (!entryTimeStr && this.appointmentData.appointmentDate && this.appointmentData.appointmentTime) {
        entryTimeStr = this.appointmentData.appointmentDate + ' ' + this.appointmentData.appointmentTime;
      }

      if (!entryTimeStr) {
        this.countdown = '';
        this.isExpired = false;
        return;
      }

      const entryTime = new Date(entryTimeStr.replace(/-/g, '/'));
      const now = new Date();
      const diff = entryTime - now;

      if (diff <= 0) {
        this.isExpired = true;
        this.countdown = '已过期';
        // 更新二维码颜色为红色
        this.appointmentData.qrColor = '2';
        // 清理定时器
        if (this.countdownTimer) {
          clearInterval(this.countdownTimer);
          this.countdownTimer = null;
        }
        return;
      }

      this.isExpired = false;

      // 计算时间差
      const days = Math.floor(diff / (1000 * 60 * 60 * 24));
      const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((diff % (1000 * 60)) / 1000);

      // 格式化显示（始终精确到秒）
      if (days > 0) {
        this.countdown = `${days}天${hours}小时${minutes}分${seconds}秒`;
      } else if (hours > 0) {
        this.countdown = `${hours}小时${minutes}分${seconds}秒`;
      } else if (minutes > 0) {
        this.countdown = `${minutes}分${seconds}秒`;
      } else {
        this.countdown = `${seconds}秒`;
      }
    },

    // 获取预约类型
    getAppointmentType(type) {
      const typeMap = {
        0: '食用农产品预约',
        1: '农批市场入场销售预约',
      };
      return typeMap[type] || '普通预约';
    },

    // 格式化日期时间
    formatDateTime(dateStr) {
      if (!dateStr) return '';
      // 处理iOS兼容性问题：将 'yyyy-MM-dd HH:mm:ss' 格式转换为 iOS 支持的 'yyyy-MM-ddTHH:mm:ss' 格式
      if (dateStr.includes(' ') && dateStr.includes('-') && !dateStr.includes('T')) {
        dateStr = dateStr.replace(' ', 'T');
      }
      const date = new Date(dateStr);
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      return `${year}-${month}-${day} ${hours}:${minutes}`;
    },

    // 格式化商品分类
    formatGoodsCategory(category) {
      const categoryMap = {
        0: '蔬菜',
        1: '水果',
        2: '肉类',
        3: '水产',
        4: '粮油',
        5: '副食品',
        6: '调味品',
        7: '其他',
      };
      return categoryMap[category] || category || '其他';
    },

    // 预览图片
    previewImage(url) {
      if (!url) return;
      uni.previewImage({
        urls: [url],
        current: 0,
      });
    },

    // 显示二维码
    showQrCode() {
      // 滚动到二维码位置
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 300,
      });
    },

    // 取消预约
    cancelAppointment() {
      uni.showModal({
        title: '确认取消',
        content: '确定要取消这个预约申请吗？',
        success: async (res) => {
          if (res.confirm) {
            try {
              const response = await delAppointment(this.applyId);
              if (response.code === 200) {
                uni.showToast({ title: '预约已取消', icon: 'success' });
                setTimeout(() => {
                  uni.navigateBack();
                }, 1500);
              }
            } catch (error) {
              console.error('取消预约失败:', error);
              uni.showToast({ title: '取消失败', icon: 'error' });
            }
          }
        },
      });
    },

    // 返回
    goBack() {
      uni.navigateBack();
    },

    // 切换单个商品的展开状态
    toggleGoodsExpand(index) {
      this.$set(this.expandedGoods, index, !this.expandedGoods[index]);
    },

    // 切换所有商品的展开状态
    toggleAllGoods() {
      this.allGoodsExpanded = !this.allGoodsExpanded;
      if (this.appointmentData.goodsList) {
        this.appointmentData.goodsList.forEach((item, index) => {
          this.$set(this.expandedGoods, index, this.allGoodsExpanded);
        });
      }
    },

    // 获取流程节点图标
    getFlowIcon(status) {
      const iconMap = {
        completed: 'checkbox-filled',
        current: 'circle-filled',
        pending: 'circle',
        error: 'close-filled',
      };
      return iconMap[status] || 'circle';
    },

    // 获取流程节点颜色
    getFlowColor(status) {
      const colorMap = {
        completed: '#52c41a',
        current: '#1890ff',
        pending: '#d9d9d9',
        error: '#ff4d4f',
      };
      return colorMap[status] || '#d9d9d9';
    },

    // 查看凭证
    viewVoucher(url, title) {
      if (!url) return;

      // 如果是图片，使用预览
      if (url.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/i)) {
        uni.previewImage({
          urls: [url],
          longPressActions: {
            itemList: ['保存图片'],
            success: (data) => {
              if (data.tapIndex === 0) {
                uni.saveImageToPhotosAlbum({
                  filePath: url,
                  success: () => {
                    uni.showToast({ title: '保存成功' });
                  },
                });
              }
            },
          },
        });
      } else {
        // 如果是其他文件，尝试下载
        uni.showModal({
          title: '提示',
          content: `是否下载${title}？`,
          success: (res) => {
            if (res.confirm) {
              uni.downloadFile({
                url: url,
                success: (res) => {
                  uni.openDocument({
                    filePath: res.tempFilePath,
                    showMenu: true,
                  });
                },
              });
            }
          },
        });
      }
    },
  },
};
</script>

<style scoped>
.appointment-detail {
  background-color: #f5f5f5;
  min-height: 100vh;
  padding-bottom: 100rpx;
}

.status-header {
  display: flex;
  align-items: center;
  padding: 40rpx 30rpx;
  margin: 20rpx;
  border-radius: 12rpx;
  color: #fff;
}

.status-pending {
  background: linear-gradient(135deg, #faad14, #ffc53d);
}

.status-approved {
  background: linear-gradient(135deg, #52c41a, #73d13d);
}

.status-inspection {
  background: linear-gradient(135deg, #1890ff, #40a9ff);
}

.status-rejected {
  background: linear-gradient(135deg, #ff4d4f, #ff7875);
}

.status-icon {
  margin-right: 30rpx;
}

.status-info {
  flex: 1;
}

.status-text {
  display: block;
  font-size: 32rpx;
  font-weight: bold;
  margin-bottom: 10rpx;
}

.status-desc {
  font-size: 24rpx;
  opacity: 0.9;
}

.qr-section {
  background-color: #fff;
  margin: 20rpx;
  border-radius: 12rpx;
  padding: 40rpx;
  text-align: center;
}

.qr-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.qr-code {
  width: 400rpx;
  height: 400rpx;
  border: 4rpx solid #f0f0f0;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 30rpx;
  background-color: #fff;
  padding: 20rpx;
  transition: border-color 0.3s ease;
  position: relative;
}

.qr-code.qr-border-green {
  border-color: #52c41a;
  box-shadow: 0 0 20rpx rgba(82, 196, 26, 0.2);
}

.qr-code.qr-border-yellow {
  border-color: #faad14;
  box-shadow: 0 0 20rpx rgba(250, 173, 20, 0.2);
}

.qr-code.qr-border-red {
  border-color: #ff4d4f;
  box-shadow: 0 0 20rpx rgba(255, 77, 79, 0.2);
  position: relative;
}

/* 红码遮罩层样式 */
.qr-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 77, 79, 0.95);
  border-radius: 8rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

/* 已入场遮罩层样式 */
.qr-mask.green {
  background: rgba(82, 196, 26, 0.95);
}

.mask-text {
  color: #fff;
  font-size: 32rpx;
  font-weight: bold;
  margin-top: 20rpx;
  letter-spacing: 4rpx;
}

.qr-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.qr-text {
  margin-top: 20rpx;
  font-size: 24rpx;
  color: #666;
}

.qr-info {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.qr-color-tag {
  padding: 10rpx 20rpx;
  border-radius: 20rpx;
  color: #fff;
  font-size: 24rpx;
  font-weight: bold;
  margin-bottom: 15rpx;
}

.qr-green {
  background-color: #52c41a;
}

.qr-yellow {
  background-color: #faad14;
}

.qr-red {
  background-color: #ff4d4f;
}

/* 倒计时样式 */
.countdown-box {
  margin-top: 20rpx;
  padding: 15rpx 20rpx;
  background-color: #f5f7fa;
  border-radius: 8rpx;
}

.countdown-timer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10rpx;
}

.countdown-label {
  font-size: 26rpx;
  color: #606266;
}

.countdown-value {
  font-size: 28rpx;
  font-weight: bold;
  padding: 4rpx 12rpx;
  border-radius: 6rpx;
}

.countdown-value.normal {
  color: #67c23a;
  background: #f0f9ff;
}

.countdown-value.warning {
  color: #e6a23c;
  background: #fdf6ec;
}

.countdown-value.urgent {
  color: #f56c6c;
  background: #fef0f0;
  animation: blink 1s ease-in-out infinite;
}

.countdown-value.expired {
  color: #909399;
  background: #f4f4f5;
}

.expired-notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10rpx;
  color: #ff4d4f;
}

.expired-text {
  font-size: 26rpx;
  font-weight: bold;
}

@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.6;
  }
}

.qr-desc {
  font-size: 26rpx;
  color: #666;
}

.info-section {
  background-color: #fff;
  margin: 20rpx;
  border-radius: 12rpx;
  padding: 30rpx;
}

.section-title {
  display: flex;
  align-items: center;
  margin-bottom: 30rpx;
  padding-bottom: 20rpx;
  border-bottom: 2rpx solid #f0f0f0;
}

.title-text {
  margin-left: 15rpx;
  font-size: 30rpx;
  font-weight: bold;
  color: #333;
}

.info-list {
  /* 样式已在 .info-item 中定义 */
}

.info-item {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 20rpx 0;
  border-bottom: 1rpx solid #f5f5f5;
}

.info-item:last-child {
  border-bottom: none;
}

.info-label {
  width: 180rpx;
  font-size: 28rpx;
  color: #666;
  flex-shrink: 0;
}

.info-value {
  flex: 1;
  font-size: 28rpx;
  color: #333;
  text-align: right;
  word-break: break-all;
}

.info-value.remark {
  text-align: left;
  margin-left: 20rpx;
}

/* 商品信息样式 */
.expand-toggle {
  margin-left: auto;
  font-size: 26rpx;
  color: #1890ff;
  display: flex;
  align-items: center;
  gap: 8rpx;
}

.goods-list {
  margin-top: 0;
}

.goods-card {
  border-bottom: 1rpx solid #f5f5f5;
  padding-bottom: 20rpx;
  margin-bottom: 20rpx;
}

.goods-card:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.goods-header {
  display: flex;
  align-items: center;
  padding: 25rpx 0;
  position: relative;
}

.goods-badge {
  width: 50rpx;
  height: 50rpx;
  background-color: #1890ff;
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28rpx;
  font-weight: bold;
  margin-right: 25rpx;
  flex-shrink: 0;
}

.goods-header .goods-name {
  flex: 1;
  font-size: 32rpx;
  color: #333;
  font-weight: 500;
}

.goods-content {
  padding-left: 0;
  margin-top: 0;
}

.goods-info-item {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx 0;
  min-height: 50rpx;
}

.goods-label {
  font-size: 28rpx;
  color: #666;
  flex-shrink: 0;
}

.goods-value {
  font-size: 28rpx;
  color: #333;
  text-align: right;
  flex: 1;
  margin-left: 40rpx;
}

/* 凭证样式 */
.goods-voucher-block {
  padding: 15rpx 0;
}

.goods-voucher-block .info-label {
  display: block;
  width: auto;
  font-size: 28rpx;
  color: #666;
  margin-bottom: 15rpx;
}

.voucher-content {
  width: 100%;
}

.voucher-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20rpx;
  padding-left: 0;
}

.voucher-row:last-child {
  margin-bottom: 0;
}

.voucher-name {
  font-size: 28rpx;
  color: #333;
  flex: 1;
}

.voucher-status-box {
  display: flex;
  align-items: center;
  gap: 15rpx;
}

.voucher-uploaded {
  font-size: 26rpx;
  color: #52c41a;
  background-color: #f6ffed;
  border: 1rpx solid #b7eb8f;
  padding: 6rpx 16rpx;
  border-radius: 4rpx;
  flex-shrink: 0;
}

.voucher-thumbnail {
  width: 80rpx;
  height: 80rpx;
  border-radius: 8rpx;
  border: 1rpx solid #e8e8e8;
  background-color: #f5f5f5;
}

.voucher-link {
  font-size: 28rpx;
  color: #1890ff;
  padding: 8rpx 20rpx;
}

.voucher-empty {
  font-size: 28rpx;
  color: #999;
  padding-left: 20rpx;
}

/* 新增图片预览样式 */
.image-preview {
  display: flex;
  align-items: center;
  gap: 20rpx;
}

.license-thumb {
  width: 100rpx;
  height: 100rpx;
  border-radius: 8rpx;
  border: 1px solid #d9d9d9;
}

.view-text {
  color: #1890ff;
  font-size: 24rpx;
  text-decoration: underline;
}

.bottom-actions {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #fff;
  padding: 20rpx;
  display: flex;
  gap: 20rpx;
  border-top: 2rpx solid #f0f0f0;
}

.action-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80rpx;
  border: 2rpx solid #d9d9d9;
  border-radius: 40rpx;
  background-color: #fff;
  color: #666;
}

.action-btn.primary {
  background-color: #1890ff;
  border-color: #1890ff;
  color: #fff;
}

.action-text {
  margin-left: 10rpx;
  font-size: 28rpx;
}

.action-text.cancel {
  color: #ff4d4f;
}

/* 流程状态样式 */
.process-flow {
  padding: 20rpx 0;
}

.flow-item {
  position: relative;
  display: flex;
  align-items: flex-start;
  margin-bottom: 40rpx;
}

.flow-item:last-child {
  margin-bottom: 0;
}

.flow-line {
  position: absolute;
  left: 24rpx;
  top: -40rpx;
  width: 2rpx;
  height: 40rpx;
  background-color: #e8e8e8;
}

.flow-node {
  display: flex;
  align-items: flex-start;
  width: 100%;
}

.node-icon {
  width: 48rpx;
  height: 48rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 20rpx;
  flex-shrink: 0;
  background-color: #fff;
}

.flow-completed .node-icon {
  background-color: #f6ffed;
  border: 2rpx solid #b7eb8f;
}

.flow-current .node-icon {
  background-color: #e6f7ff;
  border: 2rpx solid #91d5ff;
  animation: pulse 2s ease-in-out infinite;
}

.flow-pending .node-icon {
  background-color: #fafafa;
  border: 2rpx solid #d9d9d9;
}

.flow-error .node-icon {
  background-color: #fff2f0;
  border: 2rpx solid #ffccc7;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.4);
  }
  70% {
    box-shadow: 0 0 0 10rpx rgba(24, 144, 255, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
  }
}

.node-content {
  flex: 1;
  padding-top: 5rpx;
}

.node-title {
  font-size: 30rpx;
  color: #333;
  font-weight: 500;
  margin-bottom: 8rpx;
}

.flow-completed .node-title {
  color: #52c41a;
}

.flow-current .node-title {
  color: #1890ff;
  font-weight: bold;
}

.flow-pending .node-title {
  color: #999;
}

.flow-error .node-title {
  color: #ff4d4f;
}

.node-info {
  display: flex;
  align-items: center;
  gap: 20rpx;
  margin-bottom: 8rpx;
}

.node-time {
  font-size: 24rpx;
  color: #999;
}

.node-operator {
  font-size: 24rpx;
  color: #666;
  padding: 2rpx 12rpx;
  background-color: #f5f5f5;
  border-radius: 4rpx;
}

.node-remark {
  margin-top: 8rpx;
}

.remark-text {
  font-size: 24rpx;
  color: #ff4d4f;
  background-color: #fff2f0;
  padding: 8rpx 16rpx;
  border-radius: 4rpx;
  display: inline-block;
}
</style>
